package futbol.tacticas.concursantes.TacticaAupaAtleti;

import java.awt.Color;
import java.awt.Point;
import java.util.Random;
import java.util.Vector;

import futbol.General;
import futbol.tacticas.Comando;
import futbol.tacticas.ComandoGolpearBola;
import futbol.tacticas.ComandoIrA;
import futbol.tacticas.ComandoTiroAPuerta;
import futbol.tacticas.SituacionJugadores;
import futbol.tacticas.concursantes.Tactica;

public class TacticaAupaAtleti implements Tactica {

	Random rand = new Random();

	/** Nombre del Equipo */
	public String getNombre() {
		return "AupaAtleti";
	}

	/** Color de la camiseta */
	public Color getColor1() {
		return Color.red;
	}

	/** Color del pantalon */
	public Color getColor2() {
		return Color.blue;
	}

	/** Color del numero */
	public Color getColorNumero() {
		return Color.WHITE;
	}

	private int posiciones[][] = new int[][] { { -150, 0, 6 }, { -100, 0, 6 },
			{ -65, 60, 6 }, { -65, -60, 6 }, { -10, 30, 6 }, { 10, -30, 6 },
			{ 55, 50, 7 }, { 55, -50, 7 }, { 105, 80, 7 }, { 115, 0, 7 },
			{ 105, -80, 7 } };

	/** Retorna la coordenada x inicial del un jugador */
	public int getXInicial(int n) {
		return posiciones[n][0];
	}

	/** Retorna la coordenada y inicial del un jugador */
	public int getYInicial(int n) {
		return posiciones[n][1];
	}

	/** Retorna la fuerza de un jugador */
	public int getFuerza(int n) {
		return posiciones[n][2];
	}

	/** Retorna la velocidad de un jugador, en un equipo */
	public int getVelocidad(int n) {
		return 10 - getFuerza(n);
	}

	public double getDistancia(Point p1, Point p2) {
		return General.getDistancia(p1.x, p1.y, p2.x, p2.y);
	}

	public Point corregirLateral(Point p) {
		p.x = corregirLateral(160, p.x);
		p.y = corregirLateral(120, p.y);
		return p;
	}

	public int corregirLateral(int limite, int x) {
		if (x > limite)
			return limite * 2 - x;
		else if (x < -limite)
			return -limite * 2 - x;
		return x;
	}

	double d1, d0, a1, a0;

	Point b0 = new Point(), b1 = new Point(), b2 = new Point();

	Point _b = new Point();

	int v;

	int c, _c0 = 0;

	Point[] b;

	Point xy[] = new Point[11];

	int p[] = new int[11];

	Point[] jug = new Point[11];

	private int alcanceDisparo[] = { 0, 0, 0, 0, 0, 35, 75, 127 };

	/** Retorna las acciones a ejecutar */
	public Vector<Comando> getComandos(SituacionJugadores sj) {
		Vector<Comando> comandos = new Vector<Comando>();
		for (int i = 0; i < 11; i++) {
			jug[i] = sj.getMisJugadores()[i];
		}
		b2 = b1;
		b1 = b0;
		b0 = sj.getBola();

		a0 = General.getAngulo(0, 0, b2.x - b1.x, b2.y - b1.y);
		a1 = General.getAngulo(0, 0, b1.x - b0.x, b1.y - b0.y);
		d0 = getDistancia(b1, b0);
		d1 = getDistancia(b2, b1);
		if (d0 > 100) {
			d0 = 0;
			d1 = 0;
			b1 = new Point();
			b2 = new Point();
			_c0 = c - 1;
			_b = new Point();

		} else if (d0 > 3 && (Math.abs(a0 - a1) > .20 || Math.abs(d1 - d0) > 5)) {
			_b = b1;
			_c0 = c - 1;
		}
		double n = (double) (c - _c0);
		double d = getDistancia(b0, _b);
		v = Math.max((int) Math.round(d / n - (n + 1d) / 2d), 0);

		b = new Point[v + 1];
		for (int z = 0; z < b.length; z++)
			b[z] = new Point();
		b[v] = b0;
		if (v > 0) {
			double dist = getDistancia(_b, b0);
			double dx = (double) (b0.x - _b.x) / dist;
			double dy = (double) (b0.y - _b.y) / dist;
			_b = corregirLateral(_b);
			b0 = corregirLateral(b0);
			b1 = corregirLateral(b1);
			b2 = corregirLateral(b2);
			for (int i = v; i > 0; i--) {
				b[i - 1].x = b[i].x + (int) Math.round(dx * (double) i);
				b[i - 1].y = b[i].y + (int) Math.round(dy * (double) i);
				b[i - 1] = corregirLateral(b[i - 1]);
				if (b[i - 1].y < -120 || b[i - 1].y > 120) {
					dy = -dy;
				}
				if (b[i - 1].x < -160 || b[i - 1].x > 160) {
					dx = -dx;
				}
			}
		}

		for (int i = 0; i < 11; i++) {
			int jm = Math.max(Math.min(14, v - 1), 0);
			p[i] = -1;
			for (int j = jm; j > 0; j--) {
				d0 = Math.max(0,
						getDistancia(sj.getMisJugadores()[i], b[j]) - 10d)
						/ getVelocidad(i);
				if (d0 < v - j) {
					p[i] = v - j;
					xy[i] = b[j];
					break;
				}
			}
			if (p[i] == -1) {
				d0 = Math.ceil(Math.max(0, getDistancia(
						sj.getMisJugadores()[i], b[0]) - 10d)
						/ getVelocidad(i));
				p[i] = (int) d0;
				xy[i] = b[0];
			}
		}

		// Ganar posicion
		int min = Integer.MAX_VALUE;
		int max = 0;
		for (int i = 0; i < 11; i++) {
			min = Math.min(min, p[i]);
			max = Math.max(max, p[i]);
		}
		for (int i = 0; i < 11; i++) {
			if (p[i] < (min + max) / 2)
				comandos.add(new ComandoIrA(i, xy[i].x, xy[i].y));
			else
				comandos.add(new ComandoIrA(i, getXInicial(i), getYInicial(i)));
		}
		// Pase o disparo
		for (int i = 0; i < 11; i++) {
			if (getDistancia(jug[i], b0) <= 10) {
				if (getDistancia(b0, new Point(160, 0)) <= alcanceDisparo[getFuerza(i)]) {
					// Si el disparo alcanza
					comandos.add(new ComandoTiroAPuerta(i, 0));
				} else {
					// Si no paso al más avanzado
					int mejor = -1;
					int px = 0;
					for (int k = 0; k < 11; k++) {
						if (k != i && jug[k].x > px) {
							px = jug[k].x;
							mejor = k;
						}
					}
					if (mejor != -1) {
						comandos.add(new ComandoGolpearBola(i, jug[mejor].x,
								jug[mejor].y));
					} else {
						comandos.add(new ComandoTiroAPuerta(i, 0));
					}
				}
			}
		}
		c++;
		return comandos;
	}

}